package fr.umlv.m2.jee.spij.framework.dao.hibernate;

import fr.umlv.m2.jee.spij.framework.dao.AbstractDAO;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;

import java.io.Serializable;
import java.util.List;

/**
 * @param <K> the primary key.
 * @param <T> the type of the object.
 */
public abstract class AbstractHibernateDAO<K
        extends Serializable, T>
        extends AbstractDAO<K, T>
        implements IHibernateDAO<K, T> {

    /**
     * @return the hibernate session.
     */
    public final Session getHibernateSession() {
        return (Session) getEntityManager().getDelegate();
    }

    /**
     * @param criterion the criterion.
     *
     * @return a list of object.
     */
    public final List<T> findByCriteria(final Criterion... criterion) {
        Session session = getHibernateSession();
        Criteria criteria = session.createCriteria(getEntityType());

        for (int i = 0; i < criterion.length; ++i) {
            criteria.add(criterion[i]);
        }
        return criteria.list();

    }

    /**
     * @param instance          an object of type T instance.
     * @param excludeProperties the exclude properties.
     *
     * @return a list of T object.
     */
    public final List<T> findByExample(final T instance,
                                       final String[] excludeProperties) {
        Criteria criteria =
                getHibernateSession().createCriteria(getEntityType());
        Example example = Example.create(instance);

        for (int i = 0; i < excludeProperties.length; ++i) {
            example.excludeProperty(excludeProperties[i]);
        }
        criteria.add(example);

        return criteria.list();
    }
}
